import React, { useEffect, useState } from 'react';
import {
  Space,
  Card,
  Form,
  Input,
  InputNumber,
  Select,
  Button,
  Table,
  Modal,
  Spin,
  message
} from 'antd';
import { ExclamationCircleFilled } from '@ant-design/icons';
import columns from '../../components/columns/cityColumns';
import hasAuthority from '../../components/hasAuthority';
import { useStore, observer } from '../../store/city/storeHook';
import { trimObject } from '../../utils/dataUtils';

const CityList: React.FC = () => {
  const [searchForm] = Form.useForm();
  const [editForm] = Form.useForm();
  const [messageApi, contextHolder] = message.useMessage();
  const [modal, modalContextHolder] = Modal.useModal();

  const [isModalOpen, setIsModalOpen] = useState<boolean>(false);

  const store: any = useStore();

  const rowSelection = {
    onChange: (selectedRowKeys: React.Key[], selectedRows: any[]) => {
      store.city.selectRecord(selectedRows[0]);
    },
    getCheckboxProps: (record: any) => ({
      name: record.id
    })
  };

  const pagination = {
    showSizeChanger: true,
    showQuickJumper: true,
    pageSizeOptions: [10, 20, 30, 40, 50, 100],
    current: store.city.current + 1,
    pageSize: store.city.pageSize,
    total: store.city.total,
    onChange: (page: number, pageSize: number) => {
      store.city.setPageSize(pageSize);
      search(page - 1);
    },
    onShowSizeChange: (current: number, size: number) => {
      store.city.setPageSize(size);
      search(current - 1);
    }
  };

  const search = (pageNumber: number) => {
    const values = getSearchValues();
    store.city.fetchData(values.keyword, values.parentId, pageNumber);
  };

  const getSearchValues = () => {
    const values: any = searchForm.getFieldsValue(true);
    values.keyword = (values.keyword as string || '').trim();
    values.parentId = values.parentId as string || '';
    return values;
  };

  const editRecord = (record?: any) => {
    store.city.selectRecord(record);
    setIsModalOpen(true);
    editForm.resetFields();
    editForm.setFieldsValue(store.city.getEditRecord());
  };

  const deleteRecord = () => {
    if (!store.city.record) {
      messageApi.info('请选择要删除的记录');
      return;
    }
    modal.confirm({
      title: '确定删除当前选中的记录吗？',
      icon: <ExclamationCircleFilled />,
      onOk() {
        store.city.deleteData().then((res: any) => {
          if (res.success) {
            messageApi.info('删除成功');
            search(store.city.current);
          } else {
            messageApi.error(res.message);
          }
        });
      },
      onCancel() {}
    });
  };

  const saveRecord = (values: any) => {
    if (store.city.saving) {
      return;
    }
    editForm.setFieldsValue(trimObject(values));
    store.city.saveData(values).then((res: any) => {
      store.city.setSaving(false);
      if (res.success) {
        setIsModalOpen(false);
        messageApi.info('保存成功');
        search(store.city.current);
      } else {
        messageApi.error(res.message);
      }
    });
  };

  useEffect(() => {
    const values = store.city.conditions;
    store.city.fetchData(values.keyword, values.parentId, values.pageNumber);
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const forbiddenComponent: React.ReactNode = hasAuthority(store, 'admin');
  if (forbiddenComponent) {
    return forbiddenComponent;
  }

  return (
    <>
      {contextHolder}
      {modalContextHolder}
      <Space
        direction="vertical"
        size={[0, 16]}
        style={{ width: '100%', padding: 16 }}
      >
        <Card
          size="small"
          title={
            <Space style={{ paddingTop: 8, paddingBottom: 16 }}>
              <Space.Compact block>
                <Button
                  disabled={store.city.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => search(0)}
                >
                  查询
                </Button>
                <Button
                  disabled={store.city.loading}
                  htmlType="button"
                  onClick={() => store.city.resetConditions(searchForm)}
                >
                  重置
                </Button>
              </Space.Compact>
              <Space.Compact block>
                <Button
                  disabled={store.city.loading}
                  type="primary"
                  htmlType="button"
                  onClick={() => editRecord(null)}
                >
                  新增
                </Button>
                <Button
                  disabled={store.city.loading}
                  type="primary"
                  htmlType="button"
                  danger
                  onClick={deleteRecord}
                >
                  删除
                </Button>
              </Space.Compact>
            </Space>
          }
          style={{ paddingTop: 12 }}
        >
          <Form
            form={searchForm}
            name="searchForm"
            autoComplete="off"
            colon={false}
            layout="inline"
            disabled={store.city.loading}
            initialValues={store.city.conditions}
            className="search-form"
          >
            <Form.Item
              name="keyword"
              label="关键词"
            >
              <Input
                autoFocus
                maxLength={32}
                placeholder="名称"
                style={{ width: 160 }}
              />
            </Form.Item>
            <Form.Item
              name="parentId"
              label="省份"
            >
              <Select
                showSearch
                popupMatchSelectWidth={false}
                options={store.city.provinceOptions}
                filterOption={(input, option) =>
                  (option?.label as string).toLowerCase().includes(input.toLowerCase())
                }
                labelRender={props => props.label}
                style={{ width: 160 }}
              />
            </Form.Item>
          </Form>
        </Card>
        <Table
          columns={columns(editRecord)}
          dataSource={store.city.data}
          rowKey="id"
          loading={store.city.loading}
          bordered
          scroll={{ x: 'max-content' }}
          rowSelection={{
            type: 'radio',
            selectedRowKeys: store.city.record ? [store.city.record.id] : [],
            ...rowSelection
          }}
          pagination={pagination}
        />

        <Modal
          title="城市"
          open={isModalOpen}
          maskClosable={false}
          destroyOnHidden
          forceRender
          closable={!store.city.saving}
          confirmLoading={store.city.saving}
          style={{ minWidth: 320 }}
          onOk={() => editForm.submit()}
          onCancel={() => {
            if (!store.city.saving) setIsModalOpen(false)
          }}
          footer={(_, { OkBtn, CancelBtn }) => (
            <><OkBtn /><CancelBtn /></>
          )}
        >
          <Spin spinning={store.city.saving}>
            <Form
              form={editForm}
              name="editForm"
              autoComplete="off"
              labelCol={{ span: 6 }}
              wrapperCol={{ span: 16 }}
              preserve={false}
              onFinish={saveRecord}
              onFinishFailed={() => messageApi.warning('数据校验错误')}
            >
              <Form.Item
                name="name"
                label="名称"
                rules={[{ required: true, message: '名称不能为空' }]}
              >
                <Input maxLength={32} />
              </Form.Item>
              <Form.Item
                name="parentId"
                label="省份"
              >
                <Select
                  showSearch
                  popupMatchSelectWidth={false}
                  options={store.city.provinceOptions}
                  filterOption={(input, option) =>
                    (option?.label as string).toLowerCase().includes(input.toLowerCase())
                  }
                />
              </Form.Item>
              <Form.Item
                  name="cityNumber"
                  label="序号"
                >
                <InputNumber
                  min={1}
                  max={255}
                />
              </Form.Item>
            </Form>
          </Spin>
        </Modal>
      </Space>
    </>
  );
};

export default observer(CityList);
